package turritopsis

import (
	"ebbflow/pkg/adkr"
)

// ACSFunc defines a pluggable ACS entry compatible with sDumbo's ACS.
// It receives a context identifier (sid) and an input payload (can be nil for listen-only),
// and returns a decided batch of payloads.
type ACSFunc func(sid string, input []byte) ([][]byte, error)

// KeyRefreshFunc defines a pluggable ADKR key-refresh trigger for a single round.
// Implementations should internally perform networking via provided channels in the outer layer.
// It returns an optional round output and error.
type KeyRefreshFunc func(round int) (*adkr.KeyRefreshOutput, error)

// Config captures the top-level composition parameters for Turritopsis (sDumbo ACS + ADKR reconfiguration).
type Config struct {
	// Identity and cluster sizing
	SID string
	PID int
	N   int
	F   int

	// Number of epochs (ACS rounds) to run before exit (for experiments)
	Epochs int
	// R: ADKR execution interval (every R epochs)
	R int

    // Hooks
	ACS           ACSFunc
    KeyRefreshOne KeyRefreshFunc // optional; if nil, reconfiguration is disabled
    // KRBuilder: optional per-epoch Key-Refresh builder (can use EpochPlan to build the KR func for that epoch; takes precedence over KeyRefreshOne)
    KRBuilder     func(epoch int, plan EpochPlan) KeyRefreshFunc

	// ADKR defaults (used by the default KeyRefreshOne if provided by this package)
	ADKR adkr.ADKRHighConfig

    // Dynamic plans per epoch (optional). If empty, fallback to static N,F from this config.
    Plans []EpochPlan
    // Optional user hooks for per-epoch integration (e.g., inject KR builder/net or rebind thresholds in external systems)
    BeforeEpoch func(epoch int, plan EpochPlan) error
    AfterEpoch  func(epoch int, plan EpochPlan, kr *adkr.KeyRefreshOutput) error

    // ThresholdSetter: optional hook to map (n,f) to internal thresholds in ABA/MVBA/RBC/ACSS
    // e.g., echo = n-f, ready = f+1, output = 2f+1, k = n-2f
    ThresholdSetter func(epoch int, n, f int) error
}

// Defaults returns a shallow default configuration with no-op hooks.
func Defaults() Config {
	return Config{
		SID:    "turritopsis",
		PID:    0,
		N:      4,
		F:      1,
		Epochs: 1,
	}
}


